<template>
  <div class="dynamic-line-container" ref="echarts_instance"></div>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Emit, Prop, Ref, Watch } from 'vue-property-decorator'
import * as echarts from 'echarts'
import { Getter } from 'vuex-class'
import { Dictionary } from 'vue-router/types/router'
import { deepClone } from '@/utils/specificFunc'
type EchartsOptions = echarts.EChartsOption
@Component
class DynamicLine extends Vue {
  @Getter('theme') theme!: 'dark' | 'light'
  @Ref() echarts_instance!: HTMLElement
  @Prop({ required: true }) data!: Dictionary<string[] | number[]>
  @Prop({ default: false }) isDynamic!: boolean
  @Prop({ required: true }) controller!: Dictionary<boolean>
  chart: echarts.ECharts | null = null
  timer: NodeJS.Timer | undefined = undefined
  dark_color: string[] = ['#09B1EC', '#28DCD0', '#FFE37E', '#FFC3CE']
  light_color: string[] = ['#82C2E6', '#28DCD0', '#FFE37E', '#F37D84']
  @Watch('theme')
  theme_handler() {
    this.initEcharts()
  }
  @Watch('data', { immediate: true, deep: true })
  data_handler(newVal: Dictionary<string[] | number[]>) {
    if (!this.isDynamic) return
    this.updateSeriesData(deepClone(newVal))
  }
  @Watch('controller', { deep: true, immediate: true })
  controller_handler(newVal: Dictionary<boolean>) {
    if (!this.chart) return
    const option: EchartsOptions = {
      legend: {
        selected: newVal
      }
    }
    this.chart.setOption(option)
  }
  mounted() {
    this.initEcharts()
    if (!this.chart) return
    this.chart.on('legendselectchanged', e => {
      this.onChartSelectedChange(e)
    })
  }
  destroyed() {
    clearInterval(this.timer)
  }
  initEcharts() {
    const { xData, underway, completed, approach, overtime } = this.data
    const echartsOption: EchartsOptions = {
      tooltip: {
        trigger: 'axis',
        textStyle: {
          align: 'left'
        }
      },
      legend: {
        left: 0,
        textStyle: {
          color: this.theme === 'dark' ? '#ffffff' : '#555555'
        }
      },
      grid: {
        left: '1%',
        right: '1%',
        bottom: '1%',
        containLabel: true
      },
      toolbox: {
        itemSize: 12,
        feature: {
          saveAsImage: {
            title: '',
            icon: 'path://M427.968,192v644.202667l-0.810667,5.781333c-1.152,7.210667-2.304,8.704-8.64,17.002667l-7.168,3.925333c-15.914667,8.490667-18.282667,7.168-38.4-3.925333L138.666667,624.533333l45.269333-45.226666,180.032,180.138666V192h64zM842.666667,714.666667v64h-320v-64h320z,m-64-149.333334v64h-256v-64h256z,m-64-149.333333v64h-192v-64h192z,m-64-149.333333v64h-128v-64h128z',
            iconStyle: {
              color: this.theme === 'dark' ? '#ffffff' : '#555555',
              borderWidth: 0
            }
          }
        },
        iconStyle: {
          color: this.theme === 'dark' ? '#ffffff' : '#555555'
        }
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: this.isDynamic ? xData.slice(0, 10) : xData
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          name: '进行中',
          type: 'line',
          stack: 'Underway',
          data: this.isDynamic ? underway.slice(0, 10) : underway
        },
        {
          name: '已完成',
          type: 'line',
          stack: 'Completed',
          data: this.isDynamic ? completed.slice(0, 10) : completed
        },
        {
          name: '即将超时',
          type: 'line',
          stack: 'Approach',
          data: this.isDynamic ? approach.slice(0, 10) : approach
        },
        {
          name: '已超时',
          type: 'line',
          stack: 'Overtime',
          data: this.isDynamic ? overtime.slice(0, 10) : overtime
        }
      ],
      color: this.theme === 'dark' ? this.dark_color : this.light_color,
      textStyle: {
        color: this.theme === 'dark' ? '#ffffff' : '#555555'
      }
    }
    this.chart = echarts.init(this.echarts_instance)
    this.chart.setOption(echartsOption)
    this.chart.resize()
    window.addEventListener('resize', () => {
      if (this.chart) this.chart.resize()
    })
  }
  @Emit('onChartSelectedChange')
  onChartSelectedChange(e: unknown) {
    const { name, selected } = e as { name: string; selected: Dictionary<boolean>}
    return { name, selected }
  }
  reSliceArr<T>(endIdx: number, target: T[], origin: T[]): T[] {
    target.shift()
    target.push(origin[endIdx])
    return target
  }
  updateSeriesData(copiedData: Dictionary<string[] | number[]>) {
    if (!this.isDynamic) {
      clearInterval(this.timer)
      return
    }
    const { xData, underway, completed, approach, overtime } = copiedData
    let end_idx = 10
    const xAxis = xData.slice(0, end_idx) as string[]
    const series1 = underway.slice(0, end_idx) as number[]
    const series2 = completed.slice(0, end_idx) as number[]
    const series3 = approach.slice(0, end_idx) as number[]
    const series4 = overtime.slice(0, end_idx) as number[]
    if (this.timer) clearInterval(this.timer)
    this.timer = setInterval(() => {
      if (!this.chart) return
      const options: EchartsOptions = {
        xAxis: {
          data: this.reSliceArr(end_idx, xAxis, xData as string[])
        },
        series: [
          { data: this.reSliceArr(end_idx, series1, underway as number[]) },
          { data: this.reSliceArr(end_idx, series2, completed as number[]) },
          { data: this.reSliceArr(end_idx, series3, approach as number[]) },
          { data: this.reSliceArr(end_idx, series4, overtime as number[]) }
        ]
      }
      this.chart?.setOption(options)
      end_idx + 1 > xData.length - 1 ? (end_idx = 0) : end_idx++
    }, 10 * 1000)
  }
}
export default DynamicLine
</script>

<style lang="less" scoped>
.dynamic-line-container {
  width: 100%;
  height: 100%;
}
</style>
